﻿using Microsoft.Extensions.Options;
using Naruto.Redis.Interface;
using Naruto.Redis.Config;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;

namespace Naruto.Redis.Internal
{
    /// <summary>
    /// 
    /// </summary>
    public class RedisLock : IRedisLock
    {
        /// <summary>
        /// 锁的前缀
        /// </summary>
        private readonly string LockPrefix;

        /// <summary>
        /// 
        /// </summary>
        private readonly IRedLockConnectionFactory _redLockConnectionFactory;

        /// <summary>
        /// 日志
        /// </summary>
        private readonly ILogger<RedisLock> _logger;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="options"></param>
        /// <param name="redLockConnectionFactory"></param>
        /// <param name="logger"></param>
        public RedisLock(IOptions<RedisOptions> options, IRedLockConnectionFactory redLockConnectionFactory, ILogger<RedisLock> logger)
        {
            //初始化key的前缀
            LockPrefix = options.Value.RedisPrefix.LockPrefixKey;
            _logger = logger;
            _redLockConnectionFactory = redLockConnectionFactory;
        }

        /// <summary>
        /// 锁
        /// </summary>
        /// <param name="key">key </param>
        /// <param name="expiry">过期时间</param>
        /// <param name="waitTime">等待时间</param>
        /// <returns></returns>
        public async Task<IRedLock> LockAsync(string key, TimeSpan expiry, TimeSpan waitTime, TimeSpan delayTime, CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();
            return await RedLock.CreateAsync(_redLockConnectionFactory, _logger, LockPrefix + key, expiry, waitTime, delayTime);
        }

        /// <summary>
        /// 锁
        /// </summary>
        /// <param name="key">key </param>
        /// <param name="expiry">过期时间</param>
        /// <param name="waitTime">等待时间</param>
        /// <returns></returns>
        public async Task<IRedLock> LockAsync(string key, TimeSpan expiry, CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();
            return await RedLock.CreateAsync(_redLockConnectionFactory, _logger, LockPrefix + key, expiry, default, default);
        }

    }
}
